home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 February: Tool Chest / Apple Developer CD Series Tool Chest February 1996 (Apple Computer)(1996).iso / Sample Code / DTS QT Utilities.Aug-95 / Projects & Test Apps / MovieGWorlds / TrackGWorlds.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-17  |  10.2 KB  |  293 lines  |  [TEXT/MPCC]

  1. // INCLUDES
  2. #include "TrackGWorlds.h"
  3.  
  4.  
  5. // GLOBALS
  6. Movie                     gMovie = NULL;
  7. CWindowPtr                 gWindow = NULL;
  8.  
  9. Rect                        gMovieRect = {0, 0, 0, 0};
  10. GWorldPtr                    gTrackGWorld = NULL;            // Note that in a real program this handle should be purged later if not used.
  11. GDHandle                    gTrackGDevice =  NULL;
  12. GWorldPtr                    gComposeGWorld = NULL;            // Note that in a real program this handle should be purged later if not used.
  13. GDHandle                    gComposeGDevice =  NULL;
  14.  
  15. TimeValue                    gMovieDuration = 0L;
  16. long                        gTickCount = 0L;
  17. long                        gSampleCount = 0L;
  18. Rect                        gTimeDurationRect = { 5, 5, 10 ,110};
  19.  
  20.  
  21. // ______________________________________________________________________
  22. //•  MAIN -- Starting point.
  23. void main(void) {
  24.     EventRecord     anEvent;
  25.     OSErr        anErr = noErr;
  26.     OSType        mediaType = VideoMediaType;
  27.     
  28.     //• Initialize the needed parts.
  29.     InitMacEnvironment(6);
  30.     InitializeQTEnvironment();
  31.     if ( InitializeMovie() != noErr ) ExitToShell();        // we had problems with the movie.
  32.  
  33.     //• Draw basic strings inside the window.
  34.     DrawFpsStats(0L); 
  35.     DrawMovieFpsStats();
  36.     DrawUsageInformation();
  37.     
  38.     //• Event loop.
  39.     for(;;) {
  40.         WaitNextEvent(everyEvent, &anEvent, 60, NULL);
  41.         
  42.         if(anEvent.what == mouseDown)
  43.             break;
  44.         
  45.         if(anEvent.what == keyDown) {        
  46.             SetGWorld(gWindow, NULL);
  47.             SetMovieGWorld(gMovie, (CGrafPtr)gWindow, NULL);
  48.             GoToBeginningOfMovie(gMovie); 
  49.             StartMovie(gMovie); 
  50.             
  51.             gTickCount = TickCount();
  52.             gSampleCount = 1L;
  53.             do {
  54.                 MoviesTask(gMovie, 0);
  55.             }
  56.             while (IsMovieDone(gMovie) == false);
  57.             
  58.             gTickCount = TickCount() - gTickCount;
  59.             DrawFpsStats(gTickCount);
  60.             QTUDrawVideoFrameAtTime(gMovie, GetMovieTime(gMovie, NULL));  // nudge one last time to make sure last frame is drawn.
  61.         }
  62.     }
  63. }
  64.  
  65. // ______________________________________________________________________
  66. //• InitMacEnvironment -- Initialize the Mac Toolbox.
  67. void InitMacEnvironment(long nMasters) {
  68.     long i;
  69.  
  70.     MaxApplZone();
  71.     
  72.     for(i = 0; i <nMasters; i++)
  73.         MoreMasters();
  74.     
  75.     InitGraf(&qd.thePort);
  76.     InitFonts();
  77.     InitWindows();
  78.     InitMenus();
  79.     FlushEvents(everyEvent, 0);
  80.     TEInit();
  81.     InitCursor();
  82.     InitDialogs(NULL);
  83. }
  84.  
  85.  
  86. // ______________________________________________________________________
  87. //• InitializeQTEnvironment -- Initialize the QuickTime movie toolbox parts.
  88. void InitializeQTEnvironment(void) {
  89.     OSErr anErr = noErr;
  90.     
  91.     if( !QTUIsQuickTimeInstalled() ) {
  92.         DebugStr("\pThe QuickTime extension is not present in this system");
  93.         ExitToShell();
  94.     }
  95.  
  96.     if( (QTUGetQTVersion() >> 16 ) < 0x200 ) {
  97.         DebugStr("\pWe need QT 2.0 or higher due to APIs used in this sample, consult the sources (exit).");
  98.         ExitToShell();
  99.     }
  100.     
  101. #if powerc    
  102.     if( !QTUIsQuickTimeCFMInstalled() ) {
  103.         DebugStr("\pThe QuickTime PowerPlug extension is not available (exit)");
  104.         ExitToShell();    
  105.     }                            
  106. #endif 
  107.     
  108.     anErr = EnterMovies(); DebugAssert(anErr == noErr);
  109.     if(anErr != noErr) {
  110.         DebugStr("\pProblems with Entermovies, returning errors (exit)");
  111.         ExitToShell();
  112.     }
  113. }
  114.  
  115.  
  116. // ______________________________________________________________________
  117. //• InitializeMovie -- Initialize needed movie parts for the offscreen handling.
  118. OSErr InitializeMovie(void) {
  119.     OSErr         anErr = noErr;
  120.     Rect             windowBounds = { kWindowYStart, kWindowXStart, kWindowHeigth, kWindowLength};
  121.     Track        firstVideoTrack = NULL;
  122.     Media        firstVideoMedia = NULL;
  123.     short        mediaPixelDepth = 0;
  124.     short        monitorPixelDepth = 0;
  125.     Rect            trackRect = {0, 0, 0, 0};
  126.     CGrafPtr        aSavedPort = NULL;
  127.     GDHandle        aSavedGDevice = NULL;
  128.     CTabHandle    colorTable = NULL;
  129.     long            seed = 0L;
  130.     
  131.     //• Create the window we will use.
  132.     gWindow = (CWindowPtr) NewCWindow(NULL, &windowBounds, "\pTrack GWorld Test", true, noGrowDocProc,
  133.                                             NULL, false, 0); DebugAssert(gWindow != NULL);
  134.     SetPort((GrafPtr)gWindow);
  135.     GetGWorld(&aSavedPort, &aSavedGDevice);
  136.  
  137.     //• Get the movie.
  138.     anErr = QTUSimpleGetMovie(&gMovie); DebugAssert(anErr == noErr);
  139.     if(anErr) goto Closure;
  140.     
  141.     //• Adjust the movie box values.
  142.     GetMovieBox(gMovie, &gMovieRect); 
  143.     OffsetRect(&gMovieRect,  -gMovieRect.left,  -gMovieRect.top);
  144.     SetMovieBox(gMovie, &gMovieRect); 
  145.     AlignWindow((WindowPtr)gWindow, false,  &gMovieRect, NULL);
  146.  
  147.     //• Specify the Movie GWorld.
  148.     SetMovieGWorld(gMovie, (GWorldPtr)gWindow, NULL);
  149.     anErr = GetMoviesError(); DebugAssert(anErr == noErr); if(anErr) goto Closure;
  150.     
  151.     //• Get movie duration.
  152.     gMovieDuration = GetMovieDuration(gMovie);
  153.     
  154.     //•  Find first video track, track dimensions, pixel depth and so on (need that for the GWorld creation later).
  155.     firstVideoTrack = GetMovieIndTrackType(gMovie, 1, VideoMediaType, movieTrackMediaType); // Assume we have 2.0 installed (GetMovieINdaTrackType).
  156.     anErr = GetMoviesError(); DebugAssert(anErr == noErr); if(anErr || firstVideoTrack == NULL) goto Closure;
  157.     
  158.     anErr = QTUGetTrackRect(firstVideoTrack, &trackRect); DebugAssert(anErr == noErr);
  159.     firstVideoMedia = GetTrackMedia(firstVideoTrack); DebugAssert(firstVideoMedia != NULL);
  160.     mediaPixelDepth = QTUGetVideoMediaPixelDepth(firstVideoMedia, 1);
  161.     monitorPixelDepth = (**(**aSavedGDevice).gdPMap).pixelSize;
  162.     colorTable = (**(**aSavedGDevice).gdPMap).pmTable;
  163.     
  164.     // As we copy the whole colorTable, we don't need to worry about the ctSeed values, they are the same for all
  165.     // three GWorlds now. We yank out the value just to show how it's done, anyway...
  166.     seed = (**colorTable).ctSeed;
  167.     
  168.     //• Create our Track GWorlds (note that monitorDepth == 0 implies default monitor depth).
  169.     // If we would use initial GWorld pixmap for something, then it also makes sense to EraseRect the contents.
  170.     anErr = NewGWorld(&gTrackGWorld, monitorPixelDepth, &gMovieRect, colorTable, gTrackGDevice, 0); DebugAssert (anErr == noErr);
  171.     if(anErr) goto Closure;
  172.  
  173.     anErr = NewGWorld(&gComposeGWorld, monitorPixelDepth, &gMovieRect, colorTable, gComposeGDevice, 0); DebugAssert (anErr == noErr);
  174.     if(anErr) goto Closure;
  175.     // anErr = NewGWorld(&gTrackGWorld, mediaPixelDepth, &gMovieRect, NULL, gTrackGDevice, 0); DebugAssert (anErr == noErr);
  176.     
  177.     //• Put together our Track GWorld environment.
  178.     SetTrackGWorld(firstVideoTrack, (CGrafPtr)gTrackGWorld, gTrackGDevice, NewTrackTransferProc(MyTrackTransferProc), 0L);
  179.     
  180.     //• The following commented line could be used if we want the track transfer proc to trigger, but no redirection of the track GWorld.
  181.      // SetTrackGWorld(firstVideoTrack, NULL, NULL, NewTrackTransferProc(MyTrackTransferProc), 0L);
  182.     anErr = GetMoviesError(); DebugAssert(anErr == noErr); if(anErr) goto Closure;
  183.     
  184.     //• Update the movie so that the first frame is drawn.
  185.     anErr = QTUDrawVideoFrameAtTime(gMovie, 0L); DebugAssert(anErr == noErr);
  186.     
  187. Closure:
  188.     return anErr;
  189. }
  190.  
  191. // ______________________________________________________________________
  192. //• MyTrackTransferProc -- Callback called when movie toolbox draws to GWorld.
  193. pascal OSErr MyTrackTransferProc(Track /*theTrack*/, long /*refCon*/) {
  194.     OSErr             anErr = noErr;
  195.     PixMapHandle        trackPixMap = NULL;
  196.     PixMapHandle        composePixMap = NULL;
  197.     CGrafPtr            aSavedPort = NULL;
  198.     GDHandle            aSavedGDevice = NULL;
  199.     Str255            tempString;
  200.     long                percentage = 0L;
  201.     Rect                eraseRect = { 12 ,4, 20, 35};
  202.     
  203.     //• Bounce the sample code (needed for later statistics).
  204.     gSampleCount++;
  205.     
  206.     //• Get and lock the GWorld pixmaps.
  207.     trackPixMap = GetGWorldPixMap( (GWorldPtr)gTrackGWorld);  
  208.     if(!LockPixels(trackPixMap)) goto Closure;
  209.     
  210.     composePixMap = GetGWorldPixMap( (GWorldPtr)gComposeGWorld);  
  211.     if(!LockPixels(composePixMap)) goto Closure;
  212.     
  213.     //• Switch over to the compose GWorld  for CopyBits (the actual GWorld is already set to the correct destination (movie GWorld)). 
  214.     GetGWorld(&aSavedPort, &aSavedGDevice);  SetGWorld( (CGrafPtr)gComposeGWorld, NULL);
  215.  
  216.     //• Blit from Track GWorld into the compose GWorld.
  217.     ForeColor(blackColor); BackColor(whiteColor); 
  218.     
  219.     CopyBits( (BitMap *) *trackPixMap, (BitMap *) *composePixMap, &gMovieRect, &gMovieRect,
  220.                     srcCopy, NULL );            
  221.  
  222.     //• Draw progress bar into the compose GWorld.
  223.     PenSize(1,1); ForeColor(whiteColor); FrameRect(&gTimeDurationRect);
  224.     percentage = 100L * GetMovieTime(gMovie, NULL) / gMovieDuration;
  225.     MoveTo(5,5); ForeColor(yellowColor); PenSize(4,4); LineTo( percentage +5L, 5); 
  226.  
  227.     //• Draw percentage numbers into the main GWorld (window).
  228.     MoveTo(5,20); TextFace(bold); TextSize(9); ForeColor(redColor); 
  229.     NumToString(percentage, tempString);  DrawString(tempString); 
  230.     MoveTo(25,20); DrawString("\p%");
  231.     
  232.     //• Blit from the composite GWorld into the main screen.
  233.     SetGWorld( (CGrafPtr)gWindow, NULL);
  234.     ForeColor(blackColor); BackColor(whiteColor); 
  235.     
  236.     CopyBits( (BitMap *) *composePixMap, (BitMap *) &gWindow->portPixMap, &gMovieRect,
  237.                     &gMovieRect, srcCopy, NULL );       // blit from offscreen bitmap to movie track pixmap
  238.  
  239.     //• Restore GWorlds, unlock offscreen GWorld pixels.
  240.     SetGWorld(aSavedPort, aSavedGDevice);
  241.     UnlockPixels(trackPixMap);  UnlockPixels(composePixMap); 
  242.  
  243. Closure:
  244.     return anErr;
  245. }
  246.  
  247.  
  248. // ______________________________________________________________________
  249. //• DrawFpsStats -- Provide and draw statistics concerning how many frames were drawn per second.
  250. void DrawFpsStats(long tickCount){
  251.     Str255     theString;
  252.     Rect        eraseArea = {kDrawValuesY-20, kDrawValuesX -20, kDrawValuesY+20, kDrawValuesX+20};
  253.  
  254.     EraseRect(&eraseArea); 
  255.     
  256.     //• Display the fps values.
  257.     MoveTo(kDrawTextX, kDrawTextY); 
  258.     TextFace(bold); TextSize(9);
  259.     DrawString("\pFrames drawn/second:");
  260.     if(tickCount != 0L) {
  261.         MoveTo(kDrawValuesX, kDrawValuesY);
  262.         NumToString( (60L * gSampleCount/tickCount), theString); 
  263.         DrawString(theString);
  264.     }
  265. }
  266.  
  267.  
  268. // ______________________________________________________________________
  269. //• DrawMovieFpsStats -- Get the statistics from the movie concerning frames per second, draw this.
  270. void DrawMovieFpsStats(void) {
  271.     Str255    theString;
  272.     long        nFrames = 0L;
  273.     long        nSeconds = 0L;
  274.     
  275.     MoveTo(kDrawTextX, kDrawTextY+40);
  276.     TextFace(bold); TextSize(9);
  277.     DrawString("\pMovie stats, fps: ");
  278.     MoveTo(kDrawValuesX, kDrawValuesY + 40);
  279.  
  280.     nFrames =  gMovieDuration / QTUGetDurationOfFirstMovieSample(gMovie, VideoMediaType);
  281.     nSeconds = gMovieDuration / GetMovieTimeScale(gMovie);
  282.     NumToString( (nFrames/nSeconds), theString);
  283.     DrawString(theString);
  284. }
  285.  
  286. // ______________________________________________________________________
  287. //• DrawUsageInformation -- Draw instructions how to use this simple program.
  288. void DrawUsageInformation(void) {
  289.     TextFace(normal); TextSize(9);
  290.     MoveTo(kDrawTextX, 200); DrawString("\pHit a key to start the movie.");
  291.     MoveTo(kDrawTextX, 220); DrawString("\pClick on the mouse to terminate program.");
  292. }
  293.